home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz Kr0nlcKLeZ 1 / HaCKeRz Kr0nlcKLeZ.iso / hacking / virriiorg / ll3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-23  |  15.5 KB  |  657 lines

  1. /*=============================================================*\
  2.  * ll.c - Link Looker+Zircon                                   *
  3. \*=============================================================*/
  4.  
  5. /* Compiling examples:
  6.  
  7.    regular old ANSI/C cc:
  8.    cc -O -s -o ll ll.c
  9.  
  10.    HP-UX cc:
  11.    cc +O3 -Aa -s -DHPSUCKS -o ll ll.c
  12.  
  13.    GNU GCC:
  14.  
  15.    Linux:
  16.      gcc -O2 -fomit-frame-pointer -funroll-loops -m486 -s -Wall -o ll ll.c
  17.  
  18.    BSD, SunOS 4.1.x, Slowaris 2.x, NeXT:
  19.      gcc -O2 -funroll-loops -s -Wall -o ll ll.c */
  20.  
  21. #define VERSION "1.06"
  22. #define BUFSIZE    400             /* IRC Server buffer */
  23. #define SERVER    "irc.portal.com"          /* IRC Server        */
  24. #define PORT    6667             /* IRC Port          */
  25. #define LDELAY    30             /* Loop delay seconds*/
  26. #define TIMEOUT    30             /* connection timeout*/
  27. #define USERNAME "bleh"             /* LL's Username     */
  28. #define SENDTO "#dsk"                  /* LL Send Results To*/
  29. #define JOIN "#dsk"                    /* Channel To Join   */
  30.  
  31.  
  32. #define ESTABLISHED    1
  33. #define INPROGRESS    2
  34. #define SPLIT        1
  35.  
  36. #ifdef HPSUCKS
  37. #define _INCLUDE_HPUX_SOURCE
  38. #define _INCLUDE_XOPEN_SOURCE
  39. #define _INCLUDE_POSIX_SOURCE
  40. #endif
  41.  
  42. #include <sys/time.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <stdlib.h>
  46. #include <unistd.h>
  47. #include <sys/types.h>
  48. #include <sys/socket.h>
  49. #include <fcntl.h>
  50. #include <signal.h>
  51. #include <errno.h>
  52. #include <netinet/in.h>
  53. #include <netdb.h>
  54. #include <arpa/inet.h>
  55. #include <pwd.h>
  56.  
  57. unsigned short int session=0,link_count=0;
  58. char in[BUFSIZE],out_buf[BUFSIZE],hostname[64];
  59. int *showthem=1;
  60. char *ins=in;
  61. char serverhost[81], nick[10], user[10], realname[81], lasttime[81], msgto[30], jointhis[30], chanfin[30]; 
  62.  
  63. time_t ltime;
  64.  
  65. struct irc_server {
  66.   char *name;
  67.   char *link;
  68.   unsigned short int status;
  69.   time_t time;
  70.   struct irc_server *next;
  71. } *sl1=(struct irc_server *)0,*sl2=(struct irc_server *)0;
  72.  
  73. void do_ping(char *,char *);
  74. void do_001(char *,char *);
  75. void do_error(char *,char *);
  76. void do_364(char *,char *);
  77. void do_365(char *,char *);
  78. void do_invite(char *,char *);
  79. void do_showsplits(char *,char *);
  80.  
  81. /* prototyping is lame when the function is in the same
  82.    code, lilo outta just move the function before all
  83.    other functions that call it  :-) */
  84. char *stamp(time_t);
  85.  
  86. struct parsers {
  87.    char *cmd;
  88.    void (*func)(char *,char *);
  89. } parsefuns[] = {
  90.    { "PING", (void (*)())do_ping },
  91.    { "001", (void (*)())do_001 },
  92.    { "364",(void (*)())do_364 },
  93.    { "365", (void (*)())do_365},
  94.    { "ERROR",(void (*)())do_error},
  95.    { "INVITE",(void (*)())do_invite},
  96.    { "PRIVMSG",(void (*)())do_showsplits},
  97.    { (char *)0,(void (*)())0 }
  98. };
  99.  
  100. struct sockaddr_in server;
  101. int sock=0;
  102.  
  103.  
  104. #ifndef errno
  105. extern int errno;
  106. #endif
  107.  
  108. char *
  109. mystrerror(int err) {
  110.   /*return(sys_errlist[err]); */
  111.   return(err);
  112. }
  113.  
  114. unsigned long int
  115. resolver(char *host) {
  116.   unsigned long int ip=0L;
  117.  
  118.   if(host && *host && (ip=inet_addr(host))==-1) {
  119.     struct hostent *he;
  120.     int x=0;
  121.  
  122.     while(!(he=gethostbyname((char *)host)) && x++<3) {
  123.       fprintf(stderr,"."); fflush(stderr);
  124.       sleep(1);
  125.     }
  126.     ip=(x<3) ? *(unsigned long *)he->h_addr_list[0] : 0L;
  127.   }
  128.  
  129.   return(ip);
  130. }
  131.  
  132. void
  133. clean_sl2(void) {
  134.   while(sl2) {
  135.     struct irc_server *temp=sl2->next;
  136.     if(sl2->name)
  137.       free(sl2->name);
  138.     if(sl2->link)
  139.       free(sl2->link);
  140.     free(sl2);
  141.     sl2=temp;
  142.   }
  143.   sl2=(struct irc_server *)0;
  144. }
  145.  
  146. void
  147. exit_program(char *why) {
  148.   fprintf(stderr,"\nExiting program. (%s)\n",why);
  149.  
  150.   if(sock)
  151.     close(sock);
  152.  
  153.   while(sl1) {
  154.     struct irc_server *temp=sl1->next;
  155.     if(sl1->name)
  156.       free(sl1->name);
  157.     if(sl1->link)
  158.       free(sl1->link);
  159.     free(sl1);
  160.     sl1=temp;
  161.   }
  162.  
  163.   clean_sl2();
  164.  
  165.   if(in)
  166.     free(in);
  167.  
  168.   exit(0);
  169. }
  170.  
  171. int mystrccmp(register char *s1,register char *s2) {
  172.    while((((*s1)>='a'&&(*s1)<='z')?(*s1)-32:*s1)==
  173.         (((*s2)>='a'&&(*s2)<='z')?(*s2++)-32:*s2++))
  174.      if(*s1++==0) return 0;
  175.    return (*(unsigned char *)s1-*(unsigned char *)--s2);
  176. }
  177.  
  178. char *mstrcpy(char **to,char *from) {
  179.   if(from) {
  180.     if((*to=(char *)malloc(strlen(from)+1)))
  181.       strcpy(*to,from);
  182.   }
  183.   else
  184.     *to=(char *)0;
  185.   return(*to);
  186. }
  187.  
  188. char *digtoken(char **string,char *match) {
  189.   if(string && *string && **string) {
  190.     while(**string && strchr(match,**string))
  191.       (*string)++;
  192.     if(**string) { /* got something */
  193.       char *token=*string;
  194.       if((*string=strpbrk(*string,match))) {
  195.         *(*string)++=(char)0;
  196.         while(**string && strchr(match,**string))
  197.           (*string)++;
  198.       }
  199.       else
  200.         *string = ""; /* must be at the end */
  201.       return(token);
  202.     }
  203.   }
  204.   return((char *)0);
  205. }
  206.  
  207. void signal_handler(void) {
  208.   exit_program("caught signal");
  209. }
  210.  
  211. void signal_alarm(void) {
  212.   exit_program("timed out waiting for server interaction.");
  213. }
  214.  
  215. void
  216. out(void) {
  217.   int length=strlen(out_buf);
  218.   errno=0;
  219.   if(write(sock,out_buf,length)!=length)
  220.     exit_program(mystrerror(errno));
  221. }
  222.  
  223. void
  224. init_server(void) {
  225.   int length;
  226.  
  227.   sprintf(out_buf,"USER %s %s %s :%s\nNICK %s\nMODE %s +is\nJOIN %s\n", \
  228.     user, user, user, realname, nick, nick, jointhis);
  229.   length=strlen(out_buf);
  230.  
  231.   errno=0;
  232.  
  233.   if(write(sock,out_buf,length)==length) {
  234.     fputs("established\n",stderr);
  235.     session=ESTABLISHED;
  236.     alarm(TIMEOUT);
  237.     sprintf(out_buf,"LINKS\n");
  238.     out();
  239.   }
  240.   else
  241.     exit_program(mystrerror(errno));
  242. }
  243.  
  244. void
  245. heartbeat(void) {
  246.   strcpy(out_buf,"LINKS\n");
  247.   out();
  248.   signal(SIGALRM,(void (*)())heartbeat);
  249.   alarm(LDELAY);
  250. }
  251.  
  252. void
  253. do_364(char *from,char *left) {
  254.   struct irc_server *serv;
  255.   char *sv1,*sv2;
  256.   char *nick;
  257.  
  258.   serv=(struct irc_server *)malloc(sizeof(struct irc_server));
  259.   serv->next=sl2;
  260.  
  261.   serv->status=0;
  262.   nick=digtoken(&left," ");
  263.   sv1=digtoken(&left," ");
  264.   sv2=digtoken(&left," ");
  265.  
  266.   mstrcpy(&serv->name,sv1);
  267.   mstrcpy(&serv->link,sv2);
  268.   sl2=serv;
  269. }
  270.  
  271. int
  272. findserv(struct irc_server *serv,char *name) {
  273.   for(;serv;serv=serv->next)
  274.     if(!mystrccmp(name,serv->name))
  275.       return(1);
  276.   return(0);
  277. }
  278.  
  279. void
  280. show_split(void) {
  281.   struct irc_server *serv=sl1;
  282.  
  283.   signal(SIGHUP,(void (*)())show_split);
  284.   for(;serv;serv=serv->next) {
  285.     if(serv->status & SPLIT) {
  286.       /*printf("%s SPLIT: %s [%s]\n",stamp(serv->time),serv->name,serv->link);*/
  287.       fflush(stdout);
  288.       if (showthem) {
  289.       sprintf(out_buf,"PRIVMSG %s :Split %s\n", msgto,serv->name);
  290.       out();
  291.        }
  292.     }
  293.   }
  294. }
  295.  
  296. void
  297. do_365(char *from,char *left) {
  298.   struct irc_server *serv=sl1;
  299.  
  300.   for(;serv;serv=serv->next) {
  301.     if(!findserv(sl2,serv->name)) {
  302.       if(!(serv->status & SPLIT)) {
  303.         serv->time=time(NULL);
  304.         /*printf("%s SPLIT: %s [%s]\n",stamp(serv->time),serv->name,serv->link);*/
  305.         fflush(stdout);
  306.         if (showthem) {
  307.         sprintf(out_buf,"PRIVMSG %s :Split %s\n",msgto,serv->name);
  308.         out();
  309.         }
  310.         serv->status|=SPLIT;
  311.       }
  312.     }
  313.     else
  314.       if(serv->status & SPLIT) {
  315.         serv->time=time(NULL);
  316.         /*printf("%s MERGE: %s [%s]\n",stamp(serv->time),serv->name,serv->link);*/
  317.         fflush(stdout);
  318.         if (showthem) {
  319.         sprintf(out_buf,"PRIVMSG %s :Merge %s\n", msgto, serv->name);
  320.         out();
  321.         }
  322.         serv->status&=~SPLIT;
  323.       }
  324.   }
  325.  
  326.   serv=sl2;
  327.  
  328.   for(;serv;serv=serv->next) {
  329.     if(!findserv(sl1,serv->name)) {
  330.       struct irc_server *serv2;
  331.  
  332.       serv2=(struct irc_server *)malloc(sizeof(struct irc_server));
  333.       serv2->next=sl1;
  334.       serv2->status=0;
  335.       mstrcpy(&serv2->name,serv->name);
  336.       mstrcpy(&serv2->link,serv->link);
  337.       sl1=serv2;
  338.       serv2->time=time(NULL);
  339.       if(link_count) {
  340.         /*printf("%s ADDED: %s [%s]\n",stamp(serv2->time),serv->name,serv->link);*/
  341.         fflush(stdout);
  342.         if (showthem) {
  343.     sprintf(out_buf,"PRIVMSG %s :Added %s\n",msgto, serv->name);
  344.         out();
  345.         }
  346.       }
  347.     }
  348.   }
  349.  
  350.   link_count=1;
  351.   clean_sl2();
  352. }
  353.  
  354. void
  355. do_ping(char *from,char *left) {
  356.   sprintf(out_buf,"PING :%s\n",hostname);
  357.   out();
  358. }
  359.  
  360. void
  361. do_001(char *from,char *left) {
  362.   fprintf(stderr,"Logged into server %s as nickname %s\n\n",from,nick);
  363.   fflush(stderr);
  364.   alarm(0);
  365.   signal(SIGALRM,(void (*)())heartbeat);
  366.   alarm(LDELAY);
  367. }
  368.  
  369. void
  370. do_error(char *from,char *left) {
  371.   fprintf(stderr,"Server error: %s\n",left);
  372.   fflush(stderr);
  373. }
  374.  
  375. void
  376. do_invite(char *from,char *left) {
  377. char *thachan;
  378.  
  379. sprintf(chanfin, ":%s", jointhis);
  380.  
  381. thachan=digtoken(&left," ");
  382. thachan=digtoken(&left," ");
  383.       if(!strcmp(chanfin,thachan)) {
  384.       sprintf(out_buf,"JOIN %s\n",thachan);
  385.       out();
  386. }
  387. }
  388.  
  389. void
  390. do_showsplits(char *from, char *left) {
  391. char *thasplits;
  392. struct irc_server *serv;
  393.  
  394. thasplits=digtoken(&left," ");
  395. thasplits=digtoken(&left," ");
  396.  
  397.       if(!strcmp(":.on",thasplits)) {
  398.       showthem = 1;
  399.       sprintf(out_buf,"PRIVMSG %s :Now Showing Splits To %s\n",msgto, msgto);
  400.       out();
  401.       }
  402.       if(!strcmp(":.off",thasplits)) {
  403.       showthem = 0;
  404.       sprintf(out_buf,"PRIVMSG %s :Not Showing Splits\n",msgto);
  405.       out();
  406.       }
  407.  
  408.       if(!strcmp(":.splits",thasplits)) {
  409.       sprintf(out_buf,"PRIVMSG %s :.Current Splits.\n",jointhis);
  410.       out();
  411.       for (serv = sl1; serv; serv = serv->next) {
  412.       if (serv->status & SPLIT) {
  413.       sprintf(out_buf,"PRIVMSG %s : - %s\n",jointhis, serv->name); 
  414.       out();
  415.         }
  416.       }
  417.       sprintf(out_buf,"PRIVMSG %s :.End Of Splits.\n",jointhis);
  418.       out();
  419.     }
  420. }
  421.  
  422.  
  423. void
  424. parse2(void) {
  425.   char *from,*cmd,*left;
  426.  
  427.   if(*ins==':') {
  428.     if(!(cmd=strchr(ins,' ')))
  429.       return;
  430.     *cmd++=(char)0;
  431.     from=ins+1;
  432.   }
  433.   else {
  434.     cmd=ins;
  435.     from=(char *)0;
  436.   }
  437.   if((left=strchr(cmd,' '))) {
  438.     int command;
  439.     *left++=(char)0;
  440.     left=(*left==':') ? left+1 : left;
  441.     for(command=0;parsefuns[command].cmd;command++) {
  442.       if(!mystrccmp(parsefuns[command].cmd,cmd)) {
  443.         parsefuns[command].func(from,left);
  444.         break;
  445.       }
  446.     }
  447.   }
  448. }
  449.  
  450. void
  451. parse(int length) {
  452.   char *s=in;
  453.  
  454.   *(ins+length)=(char)0;
  455.  
  456.   for(;;) {
  457.     ins=s;
  458.     while(*s && *s!=(char)13 && *s!=(char)10)
  459.       s++;
  460.     if(*s) {
  461.       while(*s && (*s==(char)13 || *s==(char)10))
  462.         *s++=(char)0;
  463.       parse2();
  464.     }
  465.     else
  466.       break;
  467.   }
  468.   strcpy(in,ins);
  469.   ins=in+(s-ins);
  470. }
  471.  
  472. void
  473. process_server(void) {
  474.   int x=0;
  475.  
  476.   for(;;) {
  477.     fd_set rd,wr;
  478.     struct timeval timeout;
  479.  
  480.     timeout.tv_usec=0; timeout.tv_sec=1;
  481.     FD_ZERO(&rd); FD_ZERO(&wr);
  482.  
  483.     FD_SET(sock,&rd);
  484.     if(session==INPROGRESS)
  485.       FD_SET(sock,&wr);
  486.  
  487.     errno=0;
  488.  
  489. #ifdef HPSUCKS
  490.     select((size_t)FD_SETSIZE,(int *)&rd,(int *)&wr,(int *)0,(session==INPROGRESS)?(const struct timeval *)&timeout:(const struct timeval *)0);
  491. #else
  492.     select(getdtablesize(),(fd_set *)&rd,(fd_set *)&wr,(fd_set *)0,(session==INPROGRESS)?(struct timeval *)&timeout:(struct timeval *)0);
  493. #endif
  494.  
  495.     if(errno==EINTR)
  496.       continue;
  497.  
  498.     errno=0;
  499.     if(session==INPROGRESS) {
  500.       if(FD_ISSET(sock,&wr)) {
  501.         init_server();
  502.          continue;
  503.       }
  504.       else {
  505.         if(x++>=TIMEOUT)
  506.           exit_program("connection timed out");
  507.         fprintf(stderr,"."); fflush(stderr);
  508.       }
  509.     }
  510.  
  511.     if(FD_ISSET(sock,&rd)) {
  512.       int length=read(sock,ins,BUFSIZE-(ins-in));
  513.  
  514.       if(length<1) {
  515.         if(session!=INPROGRESS) {
  516.           if(!errno) {
  517.             fputs("Connection closed by foreign host.",stderr);
  518.             errno=ENOTCONN;
  519.           }
  520.           else
  521.             fprintf(stderr,"Connection to %s closed.\n",
  522.                    inet_ntoa(server.sin_addr));
  523.           fflush(stderr);
  524.         }
  525.         exit_program(mystrerror(errno));
  526.       }
  527.       if(strpbrk(in,"\x0a\x0d"))
  528.         parse(length);
  529.       else
  530.         ins=(BUFSIZE-((ins+length)-in)<1)?in:ins+length;
  531.     }
  532.   }
  533. }
  534.  
  535. char *stamp(time_t ltime) {
  536.   strftime(lasttime, 81, "%x %X", localtime(<ime));
  537.   return (char *) &lasttime;
  538. }
  539.  
  540. void
  541. main(int argc,char *argv[]) {
  542.   unsigned short int sport=PORT;
  543.   unsigned int loop;
  544.   struct passwd *passent;
  545.   
  546.   fprintf(stderr, "Link Looker v%s, written and designed by Dr. Delete.\n" \
  547.                   "                   Enhanced by Zircon.\n" \
  548.                   "Type '%s -h' or '%s --help' for more information.\n\n",
  549.     VERSION, argv[0], argv[0]);
  550.     
  551.   for(loop=1; loop<argc; loop++) {
  552.     if(!strcmp("-h", argv[loop]) || !strcmp("--help", argv[loop])) {
  553.         fprintf(stderr,"Format:\n\n" \
  554.         " %s [-h] [<nick> [<server>[:<port>] ['<irc name>' " \
  555.         "[<uname> <sendto> <channel>]]]]\n\n  where:\n\n" \
  556.         "  <nick>            is the nickname to be used (default is userid),\n" \
  557.         "  <server>          is the hostname of the server to be used,\n" \
  558.         "  <port>            is a four digit port number (default is 6667),\n" \
  559.         "  <real name field> is a description of the user (default is gecos info), and\n" \
  560.         "  <uname>           is the user account field, used only if identd\n" \
  561.         "                    has not been enabled on the user's system.\n" \
  562.         "  <sendto>          send results here. Ie Zircon, #teensex.\n" \
  563.         "  <channel>         join this channel if invited.\n", argv[0]);
  564.       exit(1);
  565.     }
  566.   }
  567.   
  568.   passent=getpwuid(getuid());
  569.  
  570.   if(argc>1)
  571.     strncpy(nick,argv[1],9);
  572.   else
  573.     strncpy(nick,passent->pw_name,9);
  574.  
  575.   if(argc>2) {
  576.     char *port=strchr(argv[2],':');
  577.     sport=(port)?atoi(port+1):sport;
  578.     strncpy(serverhost,argv[2],80);
  579.     if(port)
  580.       serverhost[port-argv[2]]=(char)0;
  581.   }
  582.   else
  583.     strncpy(serverhost,SERVER,80);
  584.     
  585.   if(argc>3)
  586.     strncpy(realname,argv[3],80);
  587.   else {
  588.     char *comma=strchr(passent->pw_gecos,',');
  589.     strncpy(realname,passent->pw_gecos,80);
  590.     if(comma)
  591.       realname[comma-(passent->pw_gecos)]=(char)0;
  592.   }
  593.  
  594.   if(argc>4)
  595.     strncpy(user,argv[4],9);
  596.   else
  597.     strncpy(user,passent->pw_name,9);
  598.  
  599.   if(argc>5)
  600.     strncpy(msgto,argv[5],30);
  601.   else
  602.     strncpy(msgto,SENDTO,30);
  603.  
  604.   if(argc>6)
  605.     strncpy(jointhis,argv[6],30);
  606.   else
  607.     strncpy(jointhis,JOIN,30);
  608.  
  609.   signal(SIGPIPE,(void (*)())signal_handler);
  610.   signal(SIGHUP,(void (*)())show_split);
  611.   signal(SIGINT,(void (*)())signal_handler);
  612.   signal(SIGTERM,(void (*)())signal_handler);
  613.   signal(SIGBUS,(void (*)())signal_handler);
  614.   signal(SIGABRT,(void (*)())signal_handler);
  615.   signal(SIGSEGV,(void (*)())signal_handler);
  616.   signal(SIGALRM,(void (*)())signal_alarm);
  617.  
  618.   errno=0;
  619.   if((sock=socket(AF_INET,SOCK_STREAM,0))>0) {
  620.     server.sin_family=AF_INET;
  621.     server.sin_port=htons(sport);
  622.     fprintf(stderr,"Resolving %s...",serverhost); fflush(stderr);
  623.     if((server.sin_addr.s_addr=resolver(serverhost))) {
  624.       fputs("done\n",stderr);
  625.       fflush(stderr);
  626.  
  627.       setsockopt(sock,SOL_SOCKET,SO_LINGER,0,0);
  628.       setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,0,0);
  629.       setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,0,0);
  630.  
  631.       fcntl(sock,F_SETFL,(fcntl(sock,F_GETFL)|O_NDELAY));
  632.  
  633.       fprintf(stderr,"Connecting to %s...",inet_ntoa(server.sin_addr));
  634.       fflush(stderr);
  635.  
  636.       errno=0;
  637.       if(connect(sock,(struct sockaddr *)&server,sizeof(server))) {
  638.         if(errno!=EINPROGRESS && errno!=EWOULDBLOCK)
  639.           exit_program(mystrerror(errno));
  640.         else
  641.           session=INPROGRESS;
  642.       }
  643.       else
  644.         init_server();
  645.  
  646.       gethostname(hostname,64);
  647.       process_server();
  648.     }
  649.     else
  650.       exit_program("resolve failed");
  651.   }
  652.   else {
  653.     fprintf(stderr,"Failed to allocate an AF_INET socket. (%s)\n", mystrerror(errno));
  654.     fflush(stderr);
  655.   }
  656. }
  657.